﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Text.Json;

namespace Coder.Configs
{
    /// <summary>
    /// 模块配置
    /// </summary>
    public class ModuleConfig
    {
        /// <summary>
        /// 可用状态
        /// </summary>
        public bool Enable { get; set; }
        /// <summary>
        /// 输入输出
        /// </summary>
        public virtual ModuleIO IO { get; set; }
        /// <summary>
        /// 可用性
        /// </summary>
        public virtual ModuleAvailabilities Availabilities { get; set; }
        /// <summary>
        /// 数据插件
        /// </summary>
        public virtual ModuleDataPlug DataPlug { get; set; }
        /// <summary>
        /// 数据对象
        /// </summary>
        public virtual ModuleData Data { get; set; }

        public ModuleConfig()
        {
            this.IO = new ModuleIO();
            this.Data = new ModuleData();
            this.DataPlug = new ModuleDataPlug();
            this.Availabilities = new ModuleAvailabilities();
        }

        /// <summary>
        /// 创建一个标准的项目模块配置
        /// </summary>
        /// <returns></returns>
        public static ModuleConfig CreateProjectModule()
        {
            ModuleConfig module = new ModuleConfig();
            module.Enable = false;
            module.IO.SourcePath = "";
            module.IO.TargetPath = "";
            module.Availabilities["Base"] = false;
            module.Availabilities["One"] = false;
            module.Availabilities["Dropdown"] = false;
            module.Availabilities["Import"] = false;
            var dataProject = new ModuleDataGroup
            {
                { "Schema", "" },
                { "Name", "" },
                { "TuofengName", "" },
                { "UnderScoreCaseName", "" },
                { "Abbr", "" },
                { "CNName", "" },
                { "NameSpace", "" },
                { "EntitiesNameSpace", "" },
                { "CachesNameSpace", "" },
                { "CoreNameSpace", "" },
                { "Creator", "" },
            };
            module.Data.Add("Project", dataProject);
            var dataEntity = new ModuleDataGroup
            {
                { "DefinePath", "" },
                { "CSharpClassCode", "" },
                { "CSharpDtoCode", "" },
                { "CSharpInputParams", "" },
                { "CSharpUpdateProperties", "" },
                { "CSharpInherit", "" },
            };
            module.Data.Add("Entity", dataEntity);
            return module;
        }

        /// <summary>
        /// 从文件加载
        /// </summary>
        /// <param name="path"></param>
        /// <param name="isCreate"></param>
        /// <returns></returns>
        public static ModuleConfig LoadFromFile(string path, bool isCreate = true)
        {
            // 生成默认配置文件
            if (!egg.IO.CheckFileExists(path))
            {
                if (isCreate)
                {
                    // 获取文件夹
                    string folder = System.IO.Path.GetDirectoryName(path) ?? "";
                    egg.IO.CreateFolder(folder);

                    // 创建一个新的配置文件
                    var module = ModuleConfig.CreateProjectModule();

                    // 保存文件
                    var content = JsonSerializer.Serialize(module);
                    egg.IO.WriteUtf8FileContent(path, content);
                    return module;
                }
                else
                {
                    return CreateProjectModule();
                }
            }
            else
            {
                // 从文件获取
                var content = egg.IO.ReadUtf8FileContent(path);
                try
                {
                    var module = JsonSerializer.Deserialize<ModuleConfig>(content);
                    return module ?? CreateProjectModule();
                }
                catch
                {
                    return CreateProjectModule();
                }
            }
        }

        /// <summary>
        /// 保存到文件
        /// </summary>
        /// <param name="path"></param>
        public void SaveToFile(string path)
        {
            var content = JsonSerializer.Serialize(this);
            egg.IO.WriteUtf8FileContent(path, content);
        }

        // 添加输入输出文件
        public static void AddModuleIOFiles(ModuleConfig module, string name, List<string> paths)
        {
            foreach (var path in paths)
            {
                ModuleIOFile file = new ModuleIOFile();
                file["SourcePath"] = path;
                file["TargetPath"] = path;
                file["ModuleName"] = name;
                module.IO.Files.Add(file);
            }
        }
        // 添加输入输出文件
        public static void AddModuleIOFile(ModuleConfig module, string name, string sourcePath, string targetPath)
        {
            ModuleIOFile file = new ModuleIOFile();
            file["SourcePath"] = sourcePath;
            file["TargetPath"] = targetPath;
            file["ModuleName"] = name;
            module.IO.Files.Add(file);
        }
    }

    // IO模块
    public class ModuleIO
    {
        /// <summary>
        /// 源路径
        /// </summary>
        public virtual string SourcePath { get; set; }
        /// <summary>
        /// 目标路径
        /// </summary>
        public virtual string TargetPath { get; set; }
        /// <summary>
        /// 目录定义集合
        /// </summary>
        public virtual List<string> Folders { get; set; }
        /// <summary>
        /// 文件定义集合
        /// </summary>
        public virtual List<ModuleIOFile> Files { get; set; }
        /// <summary>
        /// IO模块
        /// </summary>
        public ModuleIO()
        {
            this.Folders = new List<string>();
            this.Files = new List<ModuleIOFile>();
            this.SourcePath = string.Empty;
            this.TargetPath = string.Empty;
        }
    }

    // Module模块
    public class ModuleAvailabilities : ObjectList
    {
        /// <summary>
        /// Core
        /// </summary>
        public virtual bool Core => this.GetValue<bool>("Core");
        /// <summary>
        /// Base
        /// </summary>
        public virtual bool Base => this.GetValue<bool>("Base");
        /// <summary>
        /// One
        /// </summary>
        public virtual bool One => this.GetValue<bool>("One");
        /// <summary>
        /// Dropdown
        /// </summary>
        public virtual bool Dropdown => this.GetValue<bool>("Dropdown");
        /// <summary>
        /// Import
        /// </summary>
        public virtual bool Import => this.GetValue<bool>("Import");
    }

    public class ModuleIOFile : ObjectList
    {
        /// <summary>
        /// 模块名称
        /// </summary>
        public virtual string ModuleName => this.GetValue<string>("ModuleName") ?? string.Empty;
        /// <summary>
        /// 源路径
        /// </summary>
        public virtual string SourcePath => this.GetValue<string>("SourcePath") ?? string.Empty;
        /// <summary>
        /// 目标路径
        /// </summary>
        public virtual string TargetPath => this.GetValue<string>("TargetPath") ?? string.Empty;
    }

    public class ModuleDataPlug : Dictionary<string, string>
    {
    }

    public class ModuleData : Dictionary<string, ModuleDataGroup>
    {
    }

    public class ModuleDataGroup : Dictionary<string, string>
    {
    }
}
